package com.gsafety.wellsfort.service.knowledge;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.enums.CustomerTypeEnum;
import com.gsafety.wellsfort.common.enums.QuestionTypeEnum;
import com.gsafety.wellsfort.common.util.ApiResponse;
import com.gsafety.wellsfort.common.util.ResultCode;
import com.gsafety.wellsfort.dao.knowledge.*;
import com.gsafety.wellsfort.dao.security.AdminDAO;
import com.gsafety.wellsfort.domain.dto.exam.*;
import com.gsafety.wellsfort.domain.model.knowledge.*;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.vo.ExamVO;
import com.gsafety.wellsfort.domain.vo.QuestionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ExamService {
    @Autowired(required = false)
    ExamPaperDAO examDAO;
    @Autowired(required = false)
    ExamQuestionDAO examQuestionDAO;
    @Autowired(required = false)
    QuestionDAO questionDAO;
    @Autowired(required = false)
    AdminDAO adminDAO;

    public ApiResponse<ExamBaseInfoDTO> saveBaseInfo(ExamBaseInfoDTO examBaseInfoDTO) {
        ApiResponse<ExamBaseInfoDTO> apiResponse = null;
        ExamPaper exampaper = new ExamPaper();
        BeanUtils.copyProperties(examBaseInfoDTO, exampaper);
        exampaper.setUpdateTime(new Date());
        exampaper.setCurrentTotalScore(BigDecimal.ZERO);
        exampaper.setModified(LoginContextUtil.getAdmin().getId());
        if (examBaseInfoDTO.getId() != null) {
            examDAO.updateByPrimaryKeySelective(exampaper);
        } else {
            exampaper.setPublicTimes(0);
            exampaper.setCreateTime(new Date());
            exampaper.setCreator(LoginContextUtil.getAdmin().getId());
            examDAO.insertSelective(exampaper);
        }
        exampaper.setCurrentTotalScore(BigDecimal.ZERO);
        examBaseInfoDTO.setId(exampaper.getId());
        apiResponse = ApiResponse.success(examBaseInfoDTO);
        return apiResponse;
    }

    public ApiResponse<ExamSettingDTO> saveWorkSetting(ExamSettingDTO examSettingDTO) {
        ApiResponse<ExamSettingDTO> apiResponse = null;
        ExamPaper w = new ExamPaper();
        w.setId(examSettingDTO.getExamId());
        if(examSettingDTO.getCurrentTotalScore().intValue()==0){
            return ApiResponse.error(ResultCode.ERROR.getCode(),"总分为0,不能提交！");
        }
        w.setPassingScore(examSettingDTO.getPassingScore());
        w.setCurrentTotalScore(examSettingDTO.getCurrentTotalScore());
        if (w.getId() != null) {
            w.setUpdateTime(new Date());
            w.setModified(LoginContextUtil.getAdmin().getId());
            examDAO.updateByPrimaryKeySelective(w);
        }
        try {
            if (examSettingDTO.getExamQuestionSettingList().size() > 0) {
                List<ExamQuSettingDTO> workQuestionSettingList = examSettingDTO.getExamQuestionSettingList();
                for (ExamQuSettingDTO workQuInfo : workQuestionSettingList) {
                    //修改题目试卷信息;
                    Integer examQuRelId = workQuInfo.getExamQuestionRelId();
                    ExamQuestion workQu = examQuestionDAO.selectByPrimaryKey(examQuRelId);
                    workQu.setScore(workQuInfo.getScore());
                    workQu.setSerialNum(workQuInfo.getSerialNum());
                    examQuestionDAO.updateByPrimaryKeySelective(workQu);
                    //同步一下题目得分和序号;
                    Integer qId = workQu.getQuestionId();
                    Question q = questionDAO.selectByPrimaryKey(qId);
                    q.setSerialNum(workQuInfo.getSerialNum());
                    q.setScore(workQuInfo.getScore());
                    questionDAO.updateByPrimaryKeySelective(q);
                }
            }
            apiResponse = ApiResponse.success(examSettingDTO);
        } catch (Exception e) {
            e.printStackTrace();
            apiResponse = ApiResponse.error(ResultCode.ERROR, e.getMessage());
        }

        return apiResponse;
    }

    public ApiResponse removeQuestion(Integer id) {
        ApiResponse apiResponse = null;
        try {
            examQuestionDAO.deleteByPrimaryKey(id);
            apiResponse = ApiResponse.success("题目移除成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<ExamQuDTO> addQuestion(ExamQuDTO workQuDTO) {
        ApiResponse<ExamQuDTO> apiResponse = null;
        try {
            List<Integer> qIdList = workQuDTO.getQuestionIdList();
            Admin admin=LoginContextUtil.getAdmin();
            if (qIdList.size() > 0) {
                for (Integer qId : qIdList) {
                    ExamQuestion workQu = new ExamQuestion();
                    workQu.setExamId(workQuDTO.getExamId());
                    workQu.setQuestionId(qId);
                    workQu.setCreator(admin.getId());
                    workQu.setCreateTime(new Date());
                    examQuestionDAO.insertSelective(workQu);
                }
            }
            apiResponse = ApiResponse.success(workQuDTO, "题目添加成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<List<ExamVO>> findExamByPageParams(ExamQueryDTO voParams) {
        ApiResponse apiResponse = null;
        Page page = PageHelper.startPage(voParams.getPageNo(), voParams.getPageSize());
        try {
            Map paramMap = org.apache.commons.beanutils.BeanUtils.describe(voParams);
            Admin admin = LoginContextUtil.getAdmin();
            if (voParams.getResourceScope() != null && voParams.getResourceScope() != 0) {
                if (admin != null) paramMap.put("creator", LoginContextUtil.getAdmin().getId());
            }
            List<ExamPaper> resultList = examDAO.selectByParam(paramMap);
            List<ExamVO> resultVOList = new ArrayList<ExamVO>();
            String includeQuestionInfo="";
            for (ExamPaper w : resultList) {
                ExamVO wVo = new ExamVO();
                BeanUtils.copyProperties(w, wVo);
                includeQuestionInfo=QuestionTypeEnum.SINGLE_ELECTION.label+":"+examQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.SINGLE_ELECTION.value)+"、"+
                QuestionTypeEnum.MULTIPLE_CHOICE.label+":"+examQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.MULTIPLE_CHOICE.value)+"、"+
                QuestionTypeEnum.JUDGE_QUESTION.label+":"+examQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.JUDGE_QUESTION.value);
                wVo.setIncludeQuestionInfo(includeQuestionInfo);
                if (wVo.getModified() != null) {
                    admin = adminDAO.selectByPrimaryKey(wVo.getModified());
                    if (admin != null) {
                        wVo.setModifiedName(admin.getName());
                    } else {
                        wVo.setModifiedName("");
                    }
                }
                wVo.setObjectTypeText(CustomerTypeEnum.parseVal(w.getObjectType()).label);
                resultVOList.add(wVo);
            }
            PageInfo pageInfo = new PageInfo(page);
            pageInfo.setList(resultVOList);
            apiResponse = ApiResponse.success(resultVOList, (int) pageInfo.getTotal());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<List<QuestionVO>> findQuestionByPageParams(ExamQuQueryDTO dtoParams) {
        ApiResponse<List<QuestionVO>> apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        try {
            Map paramMap = org.apache.commons.beanutils.BeanUtils.describe(dtoParams);
            List<QuestionVO> resultVOList = examQuestionDAO.selectByParam(paramMap);
            for (QuestionVO qVo : resultVOList) {
                qVo.setObjectTypeText(CustomerTypeEnum.parseVal(qVo.getObjectType()).label);
                qVo.setQuestionTypeText(QuestionTypeEnum.parseVal(qVo.getExamType()).label);
            }
            PageInfo pageInfo = new PageInfo(page);
            pageInfo.setList(resultVOList);
            apiResponse = ApiResponse.success(resultVOList, (int) pageInfo.getTotal());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<List<QuestionVO>> findAddQuestionByParam(ExamQuQueryDTO dtoParams) {
        ApiResponse apiResponse = null;
        Page page = PageHelper.startPage(dtoParams.getPageNo(), dtoParams.getPageSize());
        try {
            Map paramMap = org.apache.commons.beanutils.BeanUtils.describe(dtoParams);
            List<Question> resultList = examQuestionDAO.selectAddQuestionByParam(paramMap);
            List<QuestionVO> resultVOList = new ArrayList<QuestionVO>();
            for (Question q : resultList) {
                QuestionVO qVo = new QuestionVO();
                BeanUtils.copyProperties(q, qVo);
                qVo.setObjectTypeText(CustomerTypeEnum.parseVal(q.getObjectType()).label);
                qVo.setQuestionTypeText(QuestionTypeEnum.parseVal(qVo.getExamType()).label);
                resultVOList.add(qVo);
            }
            PageInfo pageInfo = new PageInfo(page);
            pageInfo.setList(resultVOList);
            apiResponse = ApiResponse.success(resultVOList, (int) pageInfo.getTotal());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return apiResponse;
    }

    public ApiResponse<ExamVO> getExam(Integer examId) {
        ApiResponse<ExamVO> apiResponse = null;
        try {

            ExamPaper w = examDAO.selectByPrimaryKey(examId);
            ExamVO wVo = new ExamVO.VOBuilder(w).build();
            String includeQuestionInfo=QuestionTypeEnum.SINGLE_ELECTION.label+":"+examQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.SINGLE_ELECTION.value)+"、"+
                    QuestionTypeEnum.MULTIPLE_CHOICE.label+":"+examQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.MULTIPLE_CHOICE.value)+"、"+
                    QuestionTypeEnum.JUDGE_QUESTION.label+":"+examQuestionDAO.countQuestionNum(w.getId(),QuestionTypeEnum.JUDGE_QUESTION.value);
            wVo.setIncludeQuestionInfo(includeQuestionInfo);
            if (wVo.getModified() != null) {
                Admin admin = adminDAO.selectByPrimaryKey(wVo.getModified());
                if (admin != null) {
                    wVo.setModifiedName(admin.getName());
                }
            }
            apiResponse = ApiResponse.success(wVo);
        } catch (Exception e) {
            log.error(e.getMessage());
            apiResponse = ApiResponse.error(ResultCode.ERROR);
        }
        return apiResponse;
    }

    public ApiResponse deleteExam(Integer examId) {
        ApiResponse apiResponse = null;
        try {
            examDAO.deleteByPrimaryKey(examId);
            apiResponse = ApiResponse.success("试卷删除成功");
        } catch (Exception e) {
            apiResponse = ApiResponse.error();
            e.printStackTrace();
        }
        return apiResponse;
    }

    public Integer finishExamCount() {
        return examDAO.finishExamCount();
    }
}
